package com.itany.nmms.service.impl;

import com.itany.mvc.util.CommonsMultipartFile;
import com.itany.nmms.constant.DictConstant;
import com.itany.nmms.dao.ProductMapper;
import com.itany.nmms.dao.SequenceMapper;
import com.itany.nmms.entity.Product;
import com.itany.nmms.entity.ProductExample;
import com.itany.nmms.entity.Sequence;
import com.itany.nmms.entity.SequenceExample;
import com.itany.nmms.exception.FileUploadErrorException;
import com.itany.nmms.exception.ProductExistException;
import com.itany.nmms.exception.RequestParameterErrorException;
import com.itany.nmms.factory.ObjectFactory;
import com.itany.nmms.service.ProductService;
import com.itany.nmms.util.ParameterUtil;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author 石小俊
 * @date 2023年07月25日 15:04
 */
public class ProductServiceImpl implements ProductService {
    @Override
    public void addProduct(String name, String price, List<CommonsMultipartFile> files, String typeId, HttpSession session) throws RequestParameterErrorException, ProductExistException, FileUploadErrorException {
        ProductMapper productMapper = (ProductMapper) ObjectFactory.getObject("productMapper");
        SequenceMapper sequenceMapper = (SequenceMapper) ObjectFactory.getObject("sequenceMapper");
        if(ParameterUtil.isNull(name) || ParameterUtil.isNull(price) || files.isEmpty() || ParameterUtil.isNull(typeId)){
            throw new RequestParameterErrorException("请求参数有误");
        }

        // 添加商品时只有一张图片,直接从集合中取出这一张图片
        CommonsMultipartFile file = files.get(0);
        if(file.isEmpty()){
            throw new RequestParameterErrorException("上传的文件不能为空");
        }

        // 同一种类型的商品名称不能重复
        ProductExample example = new ProductExample();
        example.or()
                .andProductTypeIdEqualTo(Integer.parseInt(typeId))
                .andNameEqualTo(name);
        List<Product> products = productMapper.selectByExample(example);
        if(!products.isEmpty()){
            throw new ProductExistException("该类型的商品已经存在");
        }

        // 准备一个商品对象,用于实现添加功能
        Product product = new Product();
        product.setName(name);
        product.setPrice(Double.parseDouble(price));
        product.setProductTypeId(Integer.parseInt(typeId));

        // 生成商品编号
        // 商品编号由三部分内容组成:前缀(标志位)、日期(年月日)、序列号(长度不变,值自增1)
        // 对于前缀与日期可以直接获取,序列号需要在业务中进行生成
        // 在生成序列号的时候存在两种场景
        // 1.已经使用过序列号了,在序列号所在的表中已经存在数据
        // 2.尚未使用过序列号,在序列号所在的表中尚未存在数据
        // 根据前缀查询序列号的表,根据是否存在数据继续进行操作
        SequenceExample sequenceExample = new SequenceExample();
        sequenceExample.or()
                .andNameEqualTo(DictConstant.PRODUCT_NO_PREFIX);
        List<Sequence> sequences = sequenceMapper.selectByExample(sequenceExample);
        if(sequences.isEmpty()){
            // 如果没有查询到数据,说明尚未使用过对应的序列号
            // 创建一个初始的序列号数据
            Sequence sequence = new Sequence();
            sequence.setName(DictConstant.PRODUCT_NO_PREFIX);
            sequence.setValue(DictConstant.PRODUCT_NO_SEQUENCE_INIT_VALUE);
            // 执行序列号表的添加操作
            sequenceMapper.insertSelective(sequence);
            // 生成此时对应的商品编号
            product.setProductNo(DictConstant.PRODUCT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date())+sequence.getValue());
        } else{
            // 如果查询到数据了,由于每一种编号的序列号有且仅有一个
            // 从查询到的数据中取出对应的一个序列号的数据
            Sequence sequence = sequences.get(0);
            // 判断当前序列号的值是否达到了最大值
            if(sequence.getValue().equals(DictConstant.PRODUCT_NO_SEQUENCE_MAX_VALUE)){
                // 如果已经达到了最大值,则下一个值为初始值
                sequence.setValue(DictConstant.PRODUCT_NO_SEQUENCE_INIT_VALUE);
            } else{
                // 否则下一个值为原有值+1,且长度不变
                sequence.setValue(ParameterUtil.nextSequence(sequence.getValue()));
            }
            // 执行序列号的修改操作
            sequenceMapper.updateByPrimaryKeySelective(sequence);

            // 生成此时对应的商品编号
            product.setProductNo(DictConstant.PRODUCT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date())+sequence.getValue());
        }


        // 上传商品图片
        // 在服务器根目录创建一个用于存放所有商品图片的父目录
        // 在父目录中根据上传时的日期年月日创建一个子目录
        String path = DictConstant.PRODUCT_IMAGE_ROOT_FOLDER + new SimpleDateFormat("yyyyMMdd").format(new Date());
        String cp = session.getServletContext().getRealPath(path);
        File f = new File(cp);
        f.mkdirs();

        // 为所有的图片添加一个毫秒后缀
        String fileName = file.getOriginalFilename();
        fileName = fileName.substring(0,fileName.lastIndexOf("."))+"-"+new Date().getTime()+fileName.substring(fileName.lastIndexOf("."));

        // 设置商品图片的值,其值为相对于服务器的路径名+文件名
        product.setImage(path+"/"+fileName);

        // 添加商品
        productMapper.insertSelective(product);

        try {
            // 上传图片
            file.transferTo(new File(cp,fileName));
        } catch (Exception e) {
            e.printStackTrace();
            throw new FileUploadErrorException("上传商品图片失败");
        }

    }
}
